home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / POSTSCPT / GSVIEW / EPSTOOL.ZIP / epstool / epstool.c next >
Encoding:
C/C++ Source or Header  |  1995-11-23  |  17.3 KB  |  663 lines

  1. /* Copyright (C) 1993, 1994, 1995, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* epstool.c */
  19. #include "epstool.h"
  20.  
  21. char szVersion[] = "0.71 alpha 1995-11-23";
  22.  
  23. char iname[MAXSTR];
  24. char oname[MAXSTR];
  25. char upname[MAXSTR];
  26. char gsname[MAXSTR] = GSCOMMAND;
  27. char bmpname[MAXSTR];
  28. char devname[MAXSTR];
  29. char szScratch[] = "ep";
  30. char szAppName[] = "epstool";
  31. int resolution = 72;
  32. int page = 1;    /* default is page 1 */
  33. BOOL calc_bbox = FALSE;
  34. BOOL got_op = FALSE;
  35. BOOL debug = FALSE;
  36. BOOL quiet = FALSE;
  37. int op = 0;
  38. #define EXTRACTPS    1
  39. #define EXTRACTPRE    2
  40. #define INTERCHANGE    3
  41. #define TIFF4         4
  42. #define TIFF5        5
  43. #define TIFFGS        6
  44. #define USER        7
  45.  
  46. /* KLUDGE variables */
  47. PSDOC *doc;
  48. PSFILE psfile;
  49. OPTION option;
  50. char GVFAR *bitmap_base;
  51. LPBITMAP2 bitmap_pbmi;
  52.  
  53. /* function prototypes */
  54. BOOL load_bitmap(void);
  55. int scan_args(int argc, char *argv[]);
  56. void do_help(void);
  57. int extract_section(void);
  58. int add_preview(void);
  59. void psfile_extract_header(FILE *f);
  60. void psfile_extract_page(FILE *f, int page);
  61.  
  62. /* KLUDGE functions */
  63. LPBITMAP2 get_bitmap(void)
  64. {
  65.     return bitmap_pbmi;
  66. }
  67. void release_bitmap(void)
  68. {
  69. }
  70. void play_sound(int i)
  71. {
  72. }
  73.  
  74.  
  75. int
  76. main(int argc, char *argv[])
  77. {
  78.     if (scan_args(argc, argv))
  79.        return 1;
  80. #if defined(__EMX__) || defined(MSDOS)
  81.     setmode(fileno(stdout), O_BINARY);
  82. #endif
  83.  
  84.     strcpy(psfile.name, iname);
  85.     if ((psfile.file = fopen(psfile.name, READBIN)) == (FILE *)NULL) {
  86.        fprintf(stderr, "Can't open %s\n", psfile.name);
  87.        return 1;
  88.     }
  89.     doc = psscan(psfile.file);
  90.     if (doc == (PSDOC *)NULL) {
  91.        fprintf(stderr, "File %s does not contain DSC comments\n", psfile.name);
  92.        fclose(psfile.file);
  93.        return 1;
  94.     }
  95.  
  96.     if (op==INTERCHANGE || op==TIFF4 || op==TIFF5 || op==TIFFGS)
  97.        return add_preview();
  98.     if (op==USER)
  99.        return make_eps_user();
  100.     if (op==EXTRACTPS || op==EXTRACTPRE)
  101.        return extract_section();
  102.  
  103.     psfree(doc);
  104.     return 0;
  105. }
  106.  
  107. int
  108. extract_section(void)
  109. {
  110.     if (op == EXTRACTPS)
  111.         extract_doseps(IDM_EXTRACTPS);
  112.     else if (op == EXTRACTPRE)
  113.         extract_doseps(IDM_EXTRACTPRE);
  114.     else
  115.       fprintf(stderr, "Unknown operation %d\n", op);
  116.     return 0;
  117. }
  118.  
  119. int
  120. add_preview(void)
  121. {
  122. char ename[MAXSTR];
  123. char tempname[MAXSTR];
  124. FILE *tempfile;
  125. FILE *bmpfile;
  126. char gscommand[MAXSTR+MAXSTR];
  127. char rspname[MAXSTR];
  128. FILE *rspfile;
  129. int width, height;
  130. int code = 0;
  131.     if ((op == TIFFGS) && calc_bbox) {
  132.         calc_bbox = FALSE;
  133.         fprintf(stderr, "Can't calculate Bounding Box when using GS TIFF driver\n");
  134.         fprintf(stderr, "Using %%BoundingBox from EPS file\n");
  135.     }
  136.     if ( !calc_bbox &&
  137.              ((doc->boundingbox[URX] == doc->boundingbox[LLX]) ||
  138.           (doc->boundingbox[URY] == doc->boundingbox[LLY])) ) {
  139.        fprintf(stderr, "Bounding Box is empty");
  140.        return 1;
  141.        /* if calc_bbox, this shouldn't be an error */
  142.     }
  143.     if (!quiet && doc->numpages==0) {
  144.         fprintf(stderr, "\nFile %s does not contain any pages.\n", psfile.name);
  145.         fprintf(stderr, "Using the entire file and hoping the DSC comments are wrong.\n\n");
  146.     }
  147.         if (doc->numpages > 1) {
  148.         /* create temporary file to hold extracted page */
  149.         tempfile = gp_open_scratch_file(szScratch, ename, WRITEBIN);
  150.         if (tempfile == (FILE *)NULL) {
  151.             fprintf(stderr, "Couldn't open temporary file %s\n", ename);
  152.             return 1;
  153.         }
  154.         /* copy page to new file */
  155.         psfile_extract_header(tempfile);
  156.         psfile_extract_page(tempfile, page);
  157.         fclose(tempfile);
  158.         psfree(doc);    /* forget original file */
  159.         /* scan new file */
  160.         strcpy(psfile.name, ename);
  161.         if ((psfile.file = fopen(psfile.name, READBIN)) == (FILE *)NULL) {
  162.            fprintf(stderr, "Can't open %s\n", psfile.name);
  163.            return 1;
  164.         }
  165.         doc = psscan(psfile.file);
  166.         if (doc == (PSDOC *)NULL) {
  167.            fprintf(stderr, "File %s does not contain DSC comments\n", psfile.name);
  168.            fclose(psfile.file);
  169.            return 1;
  170.         }
  171.         page = 1;    /* we want the one and only remaining page */
  172.     }
  173.     tempfile = gp_open_scratch_file(szScratch, tempname, WRITEBIN);
  174.     if (tempfile == (FILE *)NULL) {
  175.         fprintf(stderr, "Couldn't open temporary file %s\n", tempname);
  176.         return 1;
  177.     }
  178.     rspfile = gp_open_scratch_file(szScratch, rspname, WRITEBIN);
  179.     if (rspfile == (FILE *)NULL) {
  180.         fprintf(stderr, "Couldn't open temporary response file %s\n", rspname);
  181.         if (!debug)
  182.         unlink(tempname);
  183.         return 1;
  184.     }
  185.     bmpfile = gp_open_scratch_file(szScratch, bmpname, WRITEBIN);
  186.     if (bmpfile == (FILE *)NULL) {
  187.         fprintf(stderr, "Couldn't open temporary bitmap file %s\n", bmpname);
  188.         if (!debug) {
  189.         unlink(tempname);
  190.         unlink(rspname);
  191.         }
  192.         return 1;
  193.     }
  194.     fclose(bmpfile);
  195.     if (!debug)
  196.        unlink(bmpname);
  197.     /* offset to bottom left corner of bounding box */
  198.     if (!calc_bbox)
  199.        fprintf(tempfile, "%d %d translate\r\n", -doc->boundingbox[LLX], -doc->boundingbox[LLY]);
  200.     /* calculate page size */
  201.     if (calc_bbox) {
  202.        if (doc->default_page_media) {
  203.            width = doc->default_page_media->width*resolution/72;
  204.            height = doc->default_page_media->height*resolution/72;
  205.        }
  206.        else {
  207.            width = 612*resolution/72;
  208.            height = 792*resolution/72;
  209.        }
  210.     }
  211.     else {
  212.        width = (doc->boundingbox[URX] - doc->boundingbox[LLX])*resolution/72;
  213.        height = (doc->boundingbox[URY] - doc->boundingbox[LLY])*resolution/72;
  214.     }
  215.     /* copy page to temporary file */
  216.     if (doc->numpages != 0) {
  217.         psfile_extract_header(tempfile);
  218.         psfile_extract_page(tempfile, page);
  219.         if (doc->numpages > 1)
  220.         fprintf(stderr,"Can't handle multiple page PostScript files\n");
  221.     }
  222.     else {
  223.         pscopyuntil(psfile.file, tempfile, doc->beginheader, doc->beginpreview, NULL);
  224.         pscopyuntil(psfile.file, tempfile, doc->endpreview, doc->endtrailer, NULL);
  225.     }
  226.     fprintf(tempfile, "\nquit\n");
  227.     fclose(tempfile);
  228.     if (op != TIFFGS) {
  229. #ifdef UNIX
  230.         strcpy(devname, "pbmraw");
  231. #else
  232.         strcpy(devname, "bmpmono");
  233. #endif
  234.         }
  235. #ifdef UNIX
  236.     sprintf(gscommand, "%s -dNOPAUSE -dQUIET -sDEVICE=%s -sOutputFile=\042%s\042 -r%d -g%dx%d %s",
  237.        gsname, devname, bmpname, resolution, width, height, tempname);
  238. #else
  239.     sprintf(gscommand, "-dNOPAUSE\n-dQUIET\n-sDEVICE=%s\n-sOutputFile=\042%s\042\n-r%d\n-g%dx%d\n\042%s\042",
  240.        devname, bmpname, resolution, width, height, tempname);
  241.     if (!quiet) {
  242.         fputs(gscommand, stderr);
  243.         fputs("\n", stderr);
  244.     }
  245.     fputs(gscommand, rspfile);
  246.     fclose(rspfile);
  247.     sprintf(gscommand, "%s @%s", gsname, rspname);
  248. #endif
  249.     if (!quiet)
  250.         fprintf(stderr,"%s\n", gscommand);
  251.     system(gscommand);
  252.     if (!debug) {
  253.         unlink(rspname);
  254.         unlink(tempname);
  255.     }
  256.  
  257.     if (op == TIFFGS) {
  258.         strcpy(upname, bmpname);
  259.         code = make_eps_user();    /* create user TIFF preview */
  260.         if (!debug)
  261.         unlink(bmpname);
  262.     }
  263.     else {
  264.         if (!load_bitmap()) {
  265.         if (!debug)
  266.             unlink(bmpname);
  267.         fprintf(stderr, "no bitmap\n");
  268.         return 1;
  269.         }
  270.         if (!debug)
  271.         unlink(bmpname);
  272.         /* now create new file with preview */
  273.         if (op == INTERCHANGE)
  274.         code = make_eps_interchange(calc_bbox);
  275.         else if (op == TIFF4)
  276.         code = make_eps_tiff(IDM_MAKEEPST4, calc_bbox);
  277.         else if (op == TIFF5)
  278.         code = make_eps_tiff(IDM_MAKEEPST, calc_bbox);
  279.         else
  280.         fprintf(stderr, "Unknown operation %d\n", op);
  281.     }
  282.  
  283.     if (*ename) {
  284.         fclose(psfile.file);
  285.         if (!debug)
  286.             unlink(ename);    /* remove temporary file */
  287.     }
  288.  
  289.     if (!code && !quiet)
  290.         fprintf(stderr, "Add_preview was successful\n");
  291.  
  292.     return code;
  293. }
  294.  
  295. int 
  296. scan_args(int argc, char *argv[])
  297. {
  298. char *argp;
  299. int count;
  300.     if (argc == 1) {
  301.         do_help();
  302.         return 1;
  303.     }
  304.     for (count=1, argp = argv[1]; count < argc; count++, argp=argv[count]) {
  305.       if (*argp == '-') {
  306.         switch(argp[1]) {
  307.         case 'h':
  308.           do_help();
  309.           return 1;
  310.         case 'o':
  311.           if (argp[2])
  312.               strcpy(oname, argp+2);
  313.           else {
  314.               fprintf(stderr,"Missing output filename for -o\n");
  315.               return 1;
  316.           }
  317.           break;
  318.         case 'n':
  319.           if (argp[2])
  320.               page = atoi(argp+2);
  321.           else {
  322.               fprintf(stderr,"Missing page number for -n\n");
  323.               page = atoi(argp);
  324.           }
  325.           break;
  326.         case 'r':
  327.           if (argp[2])
  328.               resolution = atoi(argp+2);
  329.           else {
  330.               fprintf(stderr,"Missing resolution for -r\n");
  331.               return 1;
  332.           }
  333.           break;
  334.         case 'b':
  335.           calc_bbox = !calc_bbox;
  336.           break;
  337.         case 'd':
  338.           debug = !debug;
  339.           break;
  340.         case 'q':
  341.           quiet = !quiet;
  342.           break;
  343.         case 'g':
  344.           if (argp[2])
  345.             strcpy(gsname, argp+2);
  346.           else {
  347.               fprintf(stderr,"Missing Ghostscript command for -g\n");
  348.               return 1;
  349.           }
  350.           break;
  351.         case 't':
  352.           if (got_op) {
  353.             fprintf(stderr,"Can't select two operations");
  354.             return 1;
  355.           }
  356.           if (argp[2]=='4') {
  357.             op = TIFF4;
  358.             got_op = TRUE;
  359.           }
  360.           else if (argp[2]=='5') {
  361.             op = TIFF5;
  362.             got_op = TRUE;
  363.           }
  364.           else if (argp[2]) {
  365.             op = TIFFGS;
  366.             got_op = TRUE;
  367.             strcpy(devname, argp+2);
  368.           }
  369.           else {
  370.               fprintf(stderr,"Missing TIFF type or device name for -t\n");
  371.               return 1;
  372.           }
  373.           break;
  374.         case 'i':
  375.           if (got_op) {
  376.             fprintf(stderr,"Can't select two operations");
  377.             return 1;
  378.           }
  379.           op = INTERCHANGE;
  380.           got_op = TRUE;
  381.           break;
  382.         case 'u':
  383.           if (got_op) {
  384.             fprintf(stderr,"Can't select two operations");
  385.             return 1;
  386.           }
  387.           op = USER;
  388.           got_op = TRUE;
  389.           if (argp[2])
  390.               strcpy(upname, argp+2);
  391.           else {
  392.               fprintf(stderr,"Missing input filename for -u\n");
  393.               return 1;
  394.           }
  395.           break;
  396.         case 'p':
  397.           if (got_op) {
  398.             fprintf(stderr,"Can't select two operations");
  399.             return 1;
  400.           }
  401.           op = EXTRACTPS;
  402.           got_op = TRUE;
  403.           break;
  404.         case 'v':
  405.           if (got_op) {
  406.             fprintf(stderr,"Can't select two operations");
  407.             return 1;
  408.           }
  409.           op = EXTRACTPRE;
  410.           got_op = TRUE;
  411.           break;
  412.         default:
  413.           fprintf(stderr,"Unknown option %s\n", argp);
  414.           return 1;
  415.         }
  416.       }
  417.       else {
  418.           /* input filename */
  419.           if (*iname) {
  420.               fprintf(stderr,"Only one input file permitted\n");
  421.               return 1;
  422.           }
  423.           strcpy(iname, argp);
  424.       }
  425.     }
  426.     option.xdpi = option.ydpi = resolution;
  427.     if (*iname == '\0') {
  428.         fprintf(stderr, "No input file specified");
  429.         return 1;
  430.     }
  431.     if (!got_op) {
  432.         fprintf(stderr, "No operation specified");
  433.         return 1;
  434.     }
  435.     return 0;
  436. }
  437.  
  438. void
  439. do_help(void)
  440. {
  441.    fprintf(stderr,"Usage:  epstool [option] operation filename\n");
  442.    fprintf(stderr,"  Copyright (C) 1995 Russell Lang.  All rights reserved.\n");
  443.    fprintf(stderr,"  Version: %s\n", szVersion);
  444.    fprintf(stderr,"  Options:\n");
  445.    fprintf(stderr,"     -b             Calculate BoundingBox from image\n");
  446.    fprintf(stderr,"     -gcommand      Ghostscript command\n");
  447.    fprintf(stderr,"     -nnumber       Page number to extract\n");
  448.    fprintf(stderr,"     -ofilename     Output filename\n");
  449.    fprintf(stderr,"     -q             Quiet (no messages)\n");
  450.    fprintf(stderr,"     -rnumber       Preview resolution in dpi\n");
  451.    fprintf(stderr,"  Operations: (one only)\n");
  452.    fprintf(stderr,"     -i             Add Interchange preview   (EPSI)\n");
  453.    fprintf(stderr,"     -t4            Add TIFF4 preview         (DOS EPS)\n");
  454.    fprintf(stderr,"     -t5            Add TIFF5 preview         (DOS EPS)\n");
  455.    fprintf(stderr,"     -ttiffg3       Add GS TIFF preview       (DOS EPS)\n");
  456.    fprintf(stderr,"     -ufilename     Add user supplied preview (DOS EPS)\n");
  457.    fprintf(stderr,"     -p             Extract PostScript        (DOS EPS)\n");
  458.    fprintf(stderr,"     -v             Extract Preview           (DOS EPS)\n");
  459. }
  460.  
  461. char *err_msgs[] = {"", "No preview in input file", "Preview file is not TIFF or Windows Metafile", ""};
  462.  
  463. void 
  464. gserror(UINT id, char *str, UINT icon, int sound)
  465. {
  466.     fprintf(stderr, "%s %s\n", err_msgs[id], str ? str : "");
  467. }
  468.  
  469. /* Create and open a scratch file with a given name prefix. */
  470. /* Write the actual file name at fname. */
  471. FILE *
  472. gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
  473. {    char *temp;
  474.     if ( (temp = getenv("TEMP")) == NULL )
  475.         _getcwd(fname, MAXSTR);
  476.     else
  477.         strcpy(fname, temp);
  478.  
  479.     /* Prevent X's in path from being converted by mktemp. */
  480.     for ( temp = fname; *temp; temp++ ) {
  481.         *temp = (char)tolower(*temp);
  482.         if (*temp == '/')
  483.             *temp = DIRSEP;
  484.     }
  485.     if ( strlen(fname) && (fname[strlen(fname)-1] != DIRSEP ) ) {
  486.         fname[strlen(fname)+1] = '\0';
  487.         fname[strlen(fname)] = DIRSEP;
  488.     }
  489.  
  490.     strcat(fname, prefix);
  491.     strcat(fname, "XXXXXX");
  492.     mktemp(fname);
  493.     return fopen(fname, mode);
  494. }
  495.  
  496. char * 
  497. _getcwd(char *dirname, int size)
  498. {
  499. #ifdef __EMX__
  500.     return _getcwd2(dirname, size);
  501. #else
  502.     return getcwd(dirname, size);
  503. #endif
  504. }
  505.  
  506.  
  507. void pserror(char *str)
  508. {
  509.     fputs(str, stderr);
  510. }
  511.  
  512.  
  513.  
  514. /* general purpose read file into memory */
  515. /* should work for files > 64k under MSDOS */
  516. /* malloc's memory to hold file contents and returns pointer to this memory */
  517. char GVFAR *
  518. read_file(char *fname)
  519. {
  520.   FILE *f;
  521.   LONG length, nread, count;
  522.   char GVFAR *base;
  523.   char GVHUGE *bp;
  524.  
  525.   if ( (f = fopen(fname, READBIN)) == (FILE *)NULL ) {
  526.     fprintf(stderr, "Can't open %s\n", fname);
  527.     return NULL;
  528.   }
  529.   fseek(f, 0, SEEK_END);
  530.   length = ftell(f);
  531.   fseek(f, 0, SEEK_SET);
  532.   if (length == 0) {
  533.     fprintf(stderr, "File %s is empty\n", fname);
  534.   }
  535. #ifdef MSDOS    /* I hate segmented architectures */
  536.   if ( (base = farmalloc(length)) == (char *)NULL )
  537. #else
  538.   if ( (base = malloc(length)) == (char *)NULL )
  539. #endif
  540.   {
  541.     fprintf(stderr, "Can't malloc memory to hold file %s\n", fname);
  542.     fclose(f);
  543.     return NULL;
  544.   }
  545.   bp = base;
  546.   while (length > 0) {
  547. #ifdef MSDOS
  548.     /* get smaller of 16k, length, remaining bytes in segment */
  549.     count = min( min(16384, length), (DWORD)(65536UL-((WORD)(bp))) );
  550. #else
  551.     count = length;
  552. #endif
  553.     nread = fread(bp, 1, (int)count, f);
  554.     if (nread == 0) {
  555.         fprintf(stderr, "Can't read file %s\n", fname);
  556.         fclose(f);
  557.         free(base);
  558.         return NULL;
  559.     }
  560.         length -= nread;
  561.     bp += nread;
  562.   }
  563.   fclose(f);
  564.   return base;  
  565. }
  566.  
  567. BOOL
  568. load_bitmap(void) 
  569. {
  570.   LPBITMAPFILE pbmf;
  571.  
  572.   /* extract some info about bitmap */
  573.   pbmf = (LPBITMAPFILE)read_file(bmpname);
  574.   if (pbmf == NULL)
  575.     return FALSE;
  576.   switch (*(char *)(pbmf)) {
  577.       case 'B':  /* BMP format */
  578.           bitmap_pbmi = (LPBITMAP2)( (char *)pbmf + sizeof(BITMAPFILE) );
  579.       break;
  580.       case 'P': /* PBMPLUS format */
  581.           bitmap_pbmi = (LPBITMAP2)(pbmf);  /* a KLUDGE */
  582.       break;
  583.       default:
  584.       fprintf(stderr,"Unknown bitmap format\n");
  585.       return FALSE;
  586.   }
  587.   return TRUE;
  588. }
  589.  
  590.  
  591. /* Copy the header to file f */
  592. /* change first line to EPSF if needed */
  593. void
  594. psfile_extract_header(FILE *f)
  595. {
  596.     char text[PSLINELENGTH];
  597.     char *comment;
  598.     BOOL pages_written = FALSE;
  599.     long position;
  600.  
  601.     fseek(psfile.file, doc->beginheader, SEEK_SET);
  602.     fgets(text, PSLINELENGTH, psfile.file);
  603.     if (doc->epsf)
  604.         fputs(text,f);
  605.     else {
  606.     switch(text[11]) {
  607.         case 1:
  608.                 fputs("%!PS-Adobe-1.0 EPSF-1.0\r\n",f);
  609.         break;
  610.         case 2:
  611.                 fputs("%!PS-Adobe-2.0 EPSF-2.0\r\n",f);
  612.         break;
  613.         default:
  614.                 fputs("%!PS-Adobe-3.0 EPSF-3.0\r\n",f);
  615.     }
  616.     }
  617.     position = ftell(psfile.file);
  618.     while ( (comment = pscopyuntil(psfile.file, f, position,
  619.                doc->endheader, "%%Pages:")) != (char *)NULL ) {
  620.     position = ftell(psfile.file);
  621.     if (pages_written) {
  622.         free(comment);
  623.         continue;
  624.     }
  625.     fprintf(f, "%%%%Pages: 1\r\n");
  626.     pages_written = TRUE;
  627.     free(comment);
  628.     }
  629. }
  630.  
  631. /* Copy the selected page and trailer to file f */
  632. void
  633. psfile_extract_page(FILE *f, int page)
  634. {
  635.     char *comment;
  636.     int i;
  637.     long position;
  638.  
  639.     /* don't copy preview because we might be adding our own */
  640.     pscopyuntil(psfile.file, f, doc->begindefaults, doc->enddefaults, NULL);
  641.     pscopyuntil(psfile.file, f, doc->beginprolog, doc->endprolog, NULL);
  642.     pscopyuntil(psfile.file, f, doc->beginsetup, doc->endsetup, NULL);
  643.  
  644.     if (doc->pageorder == DESCEND) 
  645.     i = (doc->numpages - 1) - page;
  646.     else
  647.     i = page - 1;
  648.     comment = pscopyuntil(psfile.file, f, doc->pages[i].begin,
  649.               doc->pages[i].end, "%%Page:");
  650.     fprintf(f, "%%%%Page: %s %d\r\n",
  651.         doc->pages[i].label, page++);
  652.     free(comment);
  653.     pscopyuntil(psfile.file, f, -1, doc->pages[i].end, NULL);
  654.  
  655.     position = doc->begintrailer;
  656.     while ( (comment = pscopyuntil(psfile.file, f, position,
  657.                doc->endtrailer, "%%Pages:")) != (char *)NULL ) {
  658.     position = ftell(psfile.file);
  659.     free(comment);
  660.     }
  661. }
  662.  
  663.